package com.ideal.manage.esms.service.report;

import com.alibaba.fastjson.JSONObject;
import com.ideal.manage.esms.bean.DTO.PageDto;
import com.ideal.manage.esms.bean.esms.EsmsIntegration;
import com.ideal.manage.esms.bean.project.EquipmentManage;
import com.ideal.manage.esms.bean.project.ParameterInfo;
import com.ideal.manage.esms.bean.project.ProjectManage;
import com.ideal.manage.esms.bean.report.Report;
import com.ideal.manage.esms.bean.sys.User;
import com.ideal.manage.esms.config.shiro.MyShiroRealm;
import com.ideal.manage.esms.repository.framework.MySpecification;
import com.ideal.manage.esms.repository.framework.SpecificationOperator;
import com.ideal.manage.esms.repository.integration.IntegrationRepository;
import com.ideal.manage.esms.repository.programme.ParameterInfoRepository;
import com.ideal.manage.esms.repository.project.EquipmentManageRepository;
import com.ideal.manage.esms.repository.project.ProjectManageRepository;
import com.ideal.manage.esms.repository.report.ReportRepository;
import com.ideal.manage.esms.repository.system.UserProjectRepository;
import com.ideal.manage.esms.repository.system.UserRepository;
import com.ideal.manage.esms.service.monitor.Utils;
import com.ideal.manage.esms.util.DateBtnUtil;
import com.ideal.manage.esms.util.HttpRequests;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

@Service
public class ReportService {

    @Autowired
    private ReportRepository reportRepository;
    @Autowired
    private UserProjectRepository userProjectRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private EquipmentManageRepository equipmentManageRepository;

    @Autowired
    private IntegrationRepository integrationRepository;
    @Autowired
    private ProjectManageRepository projectManageRepository;
    @Autowired
    private EntityManager entityManager;

    /**
     * 月报入库
     *
     * @param name
     * @throws ParseException
     */
    public void saveReportMonth(String name) throws ParseException {
        //获取本月的最后一天
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar2 = Calendar.getInstance();
        //加一个月
        calendar2.add(Calendar.MONTH, 0);
        //设置为该月第一天
        calendar2.set(Calendar.DATE, 1);
        //再减一天即为上个月最后一天
        calendar2.add(Calendar.DATE, -1);
        String b_day_last = df.format(calendar2.getTime());
        //获取今天的时间,如果与最后一天相同则入库
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            //找到项目
            List<ProjectManage> projectManageList = getProjectManage(name);
            //入库
            for (ProjectManage projectManage : projectManageList) {
                Report reportL = new Report();
                reportL.setId(String.valueOf(UUID.randomUUID()).replaceAll("-", ""));

                String month = sdf.format(calendar2.getTime());
                reportL.setName(month + "月(" + projectManage.getName() + ")" + "月报");
                reportL.setReportCategory("1");
                try {
                    List<Date> monthData = DateBtnUtil.month();
                    Date createDate = monthData.get(1);
                    reportL.setCreateTime(createDate);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                reportL.setProjectId(projectManage.getId());
                //保存
                reportRepository.save(reportL);
            }

        }


    /**
     * 年报入库
     *
     * @param name
     * @throws ParseException
     */
    public void saveReportYear(String name) throws ParseException {
        //获取本年的最后一天的时间
        Date endDayOfYear = DateBtnUtil.getEndDayOfYear();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            //找到项目
            List<ProjectManage> projectManageList = getProjectManage(name);

            //入库
            for (ProjectManage projectManage : projectManageList) {
                Report reportL = new Report();
                reportL.setId(String.valueOf(UUID.randomUUID()).replaceAll("-", ""));

                Integer nowYear = DateBtnUtil.getNowYear();
                reportL.setName(nowYear + "年(" + projectManage.getName() + ")" + "年报");
                reportL.setReportCategory("2");
                reportL.setCreateTime(format.parse(String.valueOf(endDayOfYear)));
                reportL.setProjectId(projectManage.getId());
                //保存
                reportRepository.save(reportL);
            }
        }




    /**
     * 列表请求
     *
     * @param pageNum
     * @param request
     * @return
     */
    public PageDto findReportData(int pageNum, HttpServletRequest request) {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        List<SpecificationOperator> operators = HttpRequests.getParametersStartingWith(request, "Q_");
        MySpecification<Report> mySpecifications = new MySpecification<>(operators);
        Pageable pageable = new PageRequest(pageNum, 10, sort);
        Page<Report> page = reportRepository.findAll(mySpecifications, pageable);
        //设置PageDto
        List<Report> alarms = page.getContent();
        long total = page.getTotalElements();
        PageDto pageDto = new PageDto();
        pageDto.setRows(alarms);
        pageDto.setTotal(total);
        return pageDto;
    }

    /**
     * 年报查找createTime
     *
     * @return
     */
    public Report findCreateTimeByYear(String name) {
        //通过项目的名称找到对用的报表生成时间
        List<ProjectManage> projectManageList = getProjectManage(name);
        for (ProjectManage projectManage : projectManageList) {
            String id = projectManage.getId();
            Integer nowYear = DateBtnUtil.getNowYear();
            String reportName = nowYear + "年(" + projectManage.getName() + ")" + "年报";
            return reportRepository.findCreateTimeByYear(id, reportName);
        }
        return null;
    }

    /**
     * 月报查找crateTime
     *
     * @param name
     * @return
     */
    public Report findCreateTime(String name) {
        //通过项目的名称找到对用的报表生成时间
        List<ProjectManage> projectManageList = getProjectManage(name);
        for (ProjectManage projectManage : projectManageList) {
            String id = projectManage.getId();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            String month = sdf.format(new Date());
//            String reportName = month + "月(" + projectManage.getName() + ")" + "月报";
            String reportName = "2018-07月(" + projectManage.getName() + ")" + "月报";
            return reportRepository.findCreateTime(id, reportName);
        }
        return null;
    }

    /**
     * 抽取寻找项目的方法
     *
     * @param name
     * @return
     */
    public List<ProjectManage> getProjectManage(String name) {
        // 获取所有的项目
        List<ProjectManage> projectManageList = new ArrayList<ProjectManage>();
        // 获取当前登录用户
        MyShiroRealm.ShiroUser shiroUser = (MyShiroRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
        User user = userRepository.findOne(shiroUser.getId());
        if (StringUtils.isBlank(name)) {
            projectManageList = userProjectRepository.findProjectByUser(user);
        } else {
            projectManageList = userProjectRepository.findProjectByUserAndName(user, name);
        }
        return projectManageList;
    }

    /**
     * SOC矫正单体及SOC分布
     * @param id
     * @return
     */
    public List<String> findProjectsById(String id) {
        List<EquipmentManage> equipmentManageList = equipmentManageRepository.findByProjects(id);
        List<String>list =new ArrayList<>();
        equipmentManageList.forEach(equipmentManage -> {
            if (Integer.valueOf(equipmentManage.getEquipmentType()) > 2) {
                return;
            } else if(Integer.valueOf(equipmentManage.getEquipmentType())== 2) {

                list.add( equipmentManage.getId() );

            }
        });
        return list;
    }

    /**
     * 月报--->今日累计节省电费
     * @return
     * @param equipmentManages
     */
    public List<JSONObject> getElectricitySpare(List<String> equipmentManages) {
        //通过es查询相对的电池包的
       // ElasticsearchUtils.getElecticicitySpare();
        return null ;
    }

    /**
     * 月报-电量统计信息
     * @param projectId  项目的ID
     * @param month  yyyy-mm
     * @return
     */
    public Map<String, List> getBatteryDataMonth(String projectId,String month) throws ParseException {
        // 获取项目的ip
        ProjectManage project = projectManageRepository.findOne(projectId);
        // 存放数据
        List<Map<String,String>> batteryCdl = this.transferPowerForRangesMonth(project.getIp(),"cdl",month);
        List<Map<String,String>> batteryFdl = this.transferPowerForRangesMonth(project.getIp(),"fdl",month);
        List<Map<String,String>> batterySdf = null;

        int year = Integer.parseInt(month.split("-")[0]);
        int mon = Integer.parseInt(month.split("-")[1]);
        List<String> monthAllDays = DateBtnUtil.getMonthAllDays(year,mon);

        // 返回数据
        Map<String, List> result = new HashMap<>();

        result.put("monthAllDays", monthAllDays);
        result.put("batteryCdl", batteryCdl);
        result.put("batteryFdl", batteryFdl);
        result.put("batterySdf", batterySdf);
        return result;
    }

    /**
     * 统计cdl/fdl的积分数据
     * @param ip
     * @param type  需要查询的值,如cdl
     * @param month 月份
     * @return
     */
    public List<Map<String,String>> transferPowerForRangesMonth(String ip, String type,String month) {
        String sql = "SELECT DATE_FORMAT(`cal_time`, '%Y-%m-%d') AS time, sum(val) as val " +
                " FROM esms_integration  WHERE type =?  AND cal_time AND DATE_FORMAT(`cal_time`,'%Y-%m') = ?  AND project_ip =? GROUP BY time ORDER BY time";
        Query qry = entityManager.createNativeQuery(sql);
        qry.setParameter(1, type);
        qry.setParameter(2, month);
        qry.setParameter(3, ip);
        return qry.getResultList();
    }

    /**
     * 月报-诊断信息统计
     * @param projectId  项目的ID
     * @param month  yyyy-mm
     * @return
     */
    public Map<String, List> getDiagnoseResultInfoMonth(String projectId,String month) throws ParseException {
        // 获取项目的ip
        ProjectManage project = projectManageRepository.findOne(projectId);
        Map result = new HashMap();

        //构造返回的诊断数据格式
        result.put("dtdyyzx",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("dtsocyzx",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("dtzzyzx",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("dtrlyzx",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("wdyzx",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("dcbrl",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("xhcs",this.getDiagnoseResultInfoMonthBySetVal(project.getIp(),month,"dtdyyzx"));
        result.put("dtzz",this.getDiagnoseResultInfoMonthBydtzz(project.getIp(),month));

        return result;
    }


    /**
     * 月报-诊断信息统计实现-获取指定诊断当月最新值
     * @param ip  项目的ID
     * @param month  yyyy-mm
     * @param setVal
     * @return
     */
    public List<Object[]> getDiagnoseResultInfoMonthBySetVal(String ip,String month,String setVal) throws ParseException {
        // 存放数据
        String sql = "SELECT a.set_val, a.result_val " +
                "FROM esms_diagnose_result_info a, " +
                " ( SELECT " +
                "   max(info.create_time) last_time, " +
                " info.set_val " +
                " FROM esms_diagnose_result_info info, esms_diagnose_batch c " +
                " WHERE info.batch_id = c.id AND c.ip = ?"+
                " GROUP BY " +
                " set_val,date_format(info.create_time, '%Y-%m') ) b  " +
                " WHERE a.set_val = b.set_val " +
                " AND a.create_time = b.last_time " +
                " AND a.set_val = ? " +
                " AND date_format(a.create_time, '%Y-%m') = ? " +
                " ORDER BY " +
                " a.create_time DESC";
        Query qry = entityManager.createNativeQuery(sql);
        qry.setParameter(1, ip);
        qry.setParameter(2, setVal);
        qry.setParameter(3, month);

        return qry.getResultList();
    }

    /**
     * 月报-诊断信息统计-获取最大dtzz_***的值
     * @param ip  项目的ID
     * @param month  yyyy-mm
     * @return
     */
    public List<Object[]> getDiagnoseResultInfoMonthBydtzz(String ip,String month) throws ParseException {
                String sql = "SELECT " +
                " a.set_val, max(a.result_val) " +
                " FROM esms_diagnose_result_info a,esms_diagnose_batch c " +
                " WHERE  a.set_val like 'dtzz\\_%' AND a.batch_id = c.id " +
                " AND date_format(a.create_time, '%Y-%m') = ? AND c.ip = ? " +
                " GROUP BY set_val " +
                " ORDER BY a.result_val  limit 1 ";
        Query qry = entityManager.createNativeQuery(sql);
        qry.setParameter(1, month);
        qry.setParameter(2, ip);

        return qry.getResultList();
    }

}
